﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using SimpleData.ObjectModel;


namespace SimpleData.Infrastruture.JavaScript
{
	public sealed class JavaScriptSchemaLoader : ISchemaLoader
	{
		private List<string> schemaLookup;

		public JavaScriptSchemaLoader()
			: this( null )
		{ }

		public JavaScriptSchemaLoader( IEnumerable<string> basePaths )
		{
			if ( basePaths != null )
				this.schemaLookup = new List<string>( basePaths );
			else
				this.schemaLookup = new List<string>();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="path"></param>
		public void IncludeSchemaLibrary( string path )
		{
			this.schemaLookup.Add( path );
		}

		#region ISchemaLoader Members

		public DocumentSchema GetSchemaByName( DataObjectName qualifiedName )
		{
			string file = this.GetPathToJavaScriptSchame( qualifiedName );

			return new JavaScriptDocumentSchema( qualifiedName, File.ReadAllText( file ) );
		}

		#endregion

		private string GetPathToJavaScriptSchame(DataObjectName qualifiedName )
		{
			string fileName = String.Concat( qualifiedName.ToPath(), ".js" );

			foreach ( var path in this.schemaLookup )
			{
				string fullPath = Path.Combine( path, fileName );
				if ( File.Exists( fullPath ) )
					return fullPath;
			}

			return String.Empty;
		}
	}



	/// <summary>
	/// 
	/// </summary>
	internal static class SchemaLoaderExtensions
	{

		public static string ToPath( this IDataObjectName name )
		{
			return name.ToPath( String.Empty );
		}

		public static string ToPath( this IDataObjectName name, string pathBase )
		{
			char[] invalidChars = Path.GetInvalidPathChars();
			StringBuilder fullName = new StringBuilder( name.FullName );

			for ( int index = 0; index < fullName.Length; index++ )
			{
				char c = fullName[ index ];
				switch ( c )
				{
					case ':':
					case '.':
						fullName[ index ] = '\\';
						break;
					default:
						if ( invalidChars.Contains( c ) )
							fullName[ index ] = '-';
						break;
				}
			}

			if ( !String.IsNullOrEmpty( pathBase ) )
				return Path.Combine( pathBase, fullName.ToString() );
			else
				return fullName.ToString();
		}
	}

	
}
